package dispost

import (
	"encoding/json"
	"github.com/astaxie/beego/logs"
	"github.com/hpcloud/tail"
	"github.com/spf13/viper"
	"gopkg.in/fsnotify.v1"
	"log"
	"nodemessage.com/logbase/src/utils"
	"os"
	"strings"
)

type InitConfig struct {
	Dir          []string `desc:"log 目录"`
	Suffix       []string `desc:"日志后缀"`
	ZincUserName string   `desc:"zinc 账户名"`
	ZincUserPwd  string   `desc:"zinc 密码"`
	ZincUrl      string   `desc:"zinc url"`
}

var WatchArray map[string]*tail.Tail

var initConf *InitConfig
var appIni *viper.Viper

func GetInitConf() *InitConfig {
	return initConf
}

// init 初始化参数
func init() {
	logInit()
	appIni = viper.New()
	appIni.SetConfigType("ini")
	appIni.SetConfigName("app")
	if _, err := os.Stat("./conf"); err == nil {
		appIni.AddConfigPath("./conf")
	}
	appIni.AddConfigPath("./")
	err := appIni.ReadInConfig()
	if err != nil {
		panic(err)
	}
	logPath := appIni.GetStringSlice("log.path")
	suffix := appIni.GetStringSlice("log.suffix")
	zincUserName := appIni.GetString("zinc.username")
	zincUserPwd := appIni.GetString("zinc.pwd")
	zincUrl := appIni.GetString("zinc.url")

	initConf = &InitConfig{
		Dir:          logPath,
		Suffix:       suffix,
		ZincUserName: zincUserName,
		ZincUserPwd:  zincUserPwd,
		ZincUrl:      zincUrl,
	}
	WatchArray = make(map[string]*tail.Tail)
}

// initServer 初始化服务 监听已存在文件
func initServer() {

	for _, s := range initConf.Dir {
		if _, err := os.Stat(s); err == nil {
			dir, err := utils.GetFilesByDir(s, initConf.Suffix)
			if err != nil {
				logs.Error(err)
				return
			}
			for i := range dir {
				go WatchFileContent(dir[i])
			}
		}
	}

}

// initFileNew 监听新文件与更新
func initFileNew(dir string) *fsnotify.Watcher {
	watcher, err := fsnotify.NewWatcher()
	if err != nil {
		logs.Error(err)
		return nil
	}
	err = watcher.Add(dir)
	if err != nil {
		logs.Error(err)
		return nil
	}
	go func() {
		for {
			select {
			case ev := <-watcher.Events:
				{
					if ev.Op&fsnotify.Create == fsnotify.Create {
						for _, s := range initConf.Suffix {
							if strings.HasSuffix(ev.Name, s) {
								go WatchFileContent(ev.Name)
								break
							}
						}
					}
					if ev.Op&fsnotify.Remove == fsnotify.Remove {
						for _, s := range initConf.Suffix {
							if strings.HasSuffix(ev.Name, s) {
								t := WatchArray[ev.Name]
								if t != nil {
									_ = t.Stop()
								}
								delete(WatchArray, ev.Name)
								break
							}
						}
					}
					if ev.Op&fsnotify.Rename == fsnotify.Rename {
						for _, s := range initConf.Suffix {
							if strings.HasSuffix(ev.Name, s) {
								t := WatchArray[ev.Name]
								if t != nil {
									_ = t.Stop()
								}
								delete(WatchArray, ev.Name)
							}
						}
					}
				}
			case err := <-watcher.Errors:
				{
					log.Println("error : ", err)
					return
				}
			}
		}
	}()
	return watcher
}

// Run 启动服务
func Run() {
	logs.Info("server start success !")
	initServer()
	for _, s := range initConf.Dir {
		if _, err := os.Stat(s); err == nil {
			fileNew := initFileNew(s)
			if fileNew != nil {
				defer func(fileNew *fsnotify.Watcher) {
					err := fileNew.Close()
					if err != nil {

					}
				}(fileNew)
			}
		}
	}
	select {}
}

func logInit() {
	config := make(map[string]interface{})
	config["level"] = logs.LevelDebug

	configStr, err := json.Marshal(config)
	if err != nil {
		log.Fatal(err)
		return
	}
	err = logs.SetLogger(logs.AdapterConsole, string(configStr))
	if err != nil {
		log.Fatal(err)
		return
	}
}
